import { produce } from 'immer'
/**
 * 通过 createReducer 处理函数简化 switch 操作\
 * 通过查找表的对象的方式来编写 reducer\
 * 对象的每一个 key 都是 action type 值是 reducer 函数
 * @param {*} initState 初始化 state 状态值
 * @param {*} reducers 对象 key是 action 动作的 type 值是一个函数并且返回一个新状态
 * @param {*} extraReducers 处理外部的 reducer
 * @returns reducer 函数
 */
function createReducer(initState, reducers, extraReducers) {
  const actionsMap = new Map()
  const builder = {
    addCase(actionCreator, reducer) {
      actionsMap.set(actionCreator.type, reducer)
      return this
    }
  }
  extraReducers(builder) // 传递 builder 将外部的 action.type 和对应的处理函数缓存起来
  return function (state = initState, action) {
    const reducer = reducers[action.type] // 根据类型获取 reducer 处理函数
    // if(reducer) return reducer(state, action) // 执行子 reducer 函数
    if (reducer) {
      return produce(state, draft => {
        reducer(draft, action)
      })
    }
    // 处理外部的 action.type 和 对应的处理函数
    const caseReducer = actionsMap.get(action.type)
    if(caseReducer) {
      return produce(state, draft => {
        caseReducer(draft, action)
      })
    }
    return state // 返回新状态
  }
}

function createReducer2(initialState, builderCallback) {
  // 用于存储每种 action 类型对应的处理函数
  const actionsMap = new Map()
  const builder = {
    addCase(actionCreator, reducer) {
      actionsMap.set(actionCreator.type, reducer) // 保存动作对象的类型 + 处理函数
      return this
    }
  }
  builderCallback(builder)
  return function reducer(state = initialState, action) {
    const caseReducer = actionsMap.get(action.type)
    if (caseReducer) {
      // return caseReducer(state, action)
      return produce(state, (draft) => {
        caseReducer(draft, action)
      })
    }
    return state
  }
}

export default createReducer;
